home *** CD-ROM | disk | FTP | other *** search
- #! /usr/bin/perl
- # THE ABOVE LINE SHOULD POINT TO YOUR PERL EXECUTABLE!
- # ical2vcal
- # (c) 1998 Preston Brown
- # Part of the KOrganizer Project
- #
- # This utility will read ~/.calendar in the ical format as input, and output
- # a file in the versit vCalendar format with a .vcs extension.
- #
- # This code is covered by the GNU Public License. Please see the file
- # COPYING for more information.
- #
- # MINIMAL ERROR CHECKING! HIGHLY PRIMITIVE! YOU HAVE BEEN WARNED!
-
- # open the calendar.
- $home = $ENV{"HOME"};
- $pcount = 0;
-
- $exitstatus = 0;
-
- $filename = "$home/.calendar";
-
- if (defined($ARGV[0]) && defined($ARGV[1])) {
- $filename = $ARGV[0];
- $outfilename = $ARGV[1];
- } elsif (defined($ARGV[0])) {
- $outfilename = $ARGV[0];
- } else {
- exit -1;
- }
-
- if (!open(ICALFILE, $filename)) {
- exit -1;
- }
- if (!open(VCALFILE, ">$outfilename")) {
- exit -1;
- }
-
- $line = <ICALFILE>;
-
- &write_header;
-
- if ($line =~ /Calendar(\s+)\[v/) {
- while ($line = &getLine) {
- if (($line =~ /^Appt/) || ($line =~ /^Note/)) {
- &process_appointment;
- &write_appointment;
- } else {
- # silently skip line
- }
- }
- } else {
- # not a ical file?!
- exit -2;
- }
-
- close(ICALFILE);
- close(VCALFILE);
-
- sub getLine
- {
- $_ = <ICALFILE>;
- if (!defined($_)) {
- &write_footer;
- exit $exitstatus;
- }
- s/\\\[/\(/g;
- s/\\\]/\)/g;
- $pcount += tr/\[//;
- $pcount -= tr/\]//;
- return $_;
- }
-
- sub process_appointment
- {
- undef(%curappt);
-
- # this is a count of the total # of parentheses.
- while ($pcount) {
- $line = &getLine;
-
- # check to see if more is left to be processed.
- if ($pcount > 0) {
- # process the line.
-
- if ($line =~ /^Start/) {
- # start time (minutes since midnight)
- $_ = $line;
- ($totalmin) = /\[(\d+)\]/;
- $min = $totalmin % 60;
- $hour = int ($totalmin / 60);
- $curappt{"starthour"} = $hour;
- $curappt{"startmin"} = $min;
-
- } elsif ($line =~ /^Length/) {
- # time length (minutes)
- $_ = $line;
- ($lengthmin) = /\[(\d+)\]/;
- $min = $lengthmin % 60;
- $hour = int ($lengthmin / 60);
- $curappt{"endhour"} = $hour;
- $curappt{"endmin"} = $min;
- } elsif ($line =~ /^Uid/) {
- # unique identifier
- $_ = $line;
- ($uid) = /\[(.+)\]/;
- $curappt{"uid"} = $uid ;
- } elsif ($line =~ /^Owner/) {
- # appointment's owner
- $_ = $line;
- ($attendee) = /\[(\w+)\]/;
- $curappt{"attendee"} = $attendee;
- } elsif ($line =~ /^Contents/) {
- # description
- $description = "";
- $_ = $line;
- # special case where it's all in one place:
- if (/\[(.*)\]/) {
- $summary = $1;
- } else {
- ($summary) = /\[(.*)/;
- $_ = &getLine;
- while (!(/\]$/)) {
- chop;
- $description = $description . " " . $_;
- $_ = &getLine;
- }
- /(.*)\]$/;
- $description = $description . $1;
- }
- $curappt{"summary"} = $summary;
- if (length($description) > 0) {
- $summary = $summary . "...";
- $curappt{"description"} = $description;
- }
- } elsif ($line =~ /^Text/) {
- $description = "";
- $_ = $line;
- if (/\[\d+\s+\[(.*)\]\]/) {
- $summary = $1;
- } else {
- ($summary) = /\[\d+\s+\[(.*)$/;
- $_ = &getLine;
- while (!(/\]$/)) {
- chop;
- $description = $description . " " . $_;
- $_ = &getLine;
- }
- /^(.*)\]\]/;
- $description = $description . $1;
- }
- $curappt{"summary"} = $summary;
- if (length($description) > 0) {
- $summary = $summary . "...";
- $curappt{"description"} = $description;
- }
- } elsif ($line =~ /^Alarms/) {
- $_ = $line;
- ($alarm) = /(\d+)\]/;
- $curappt{"alarmtime"} = $alarm;
- } elsif ($line =~ /^Todo/) {
- $curappt{"todo"} = 1;
- } elsif ($line =~ /^Dates/) {
- # dates to occur on
- &process_dates;
- } elsif ($line =~ /^\]/) {
- # do nothing
- } elsif ($line =~ /^Hilite/) {
- # do nothing
- } elsif ($line =~ /^Remind/) {
- # do nothing
- } elsif ($line =~ /^Done/) {
- $curappt{"done"}=1;
- } else {
- # do nothing
- ;
- }
-
- } # if $pcount > 0
-
- } # while pcount
-
- if (defined($curappt{"starthour"})) {
- # fix up end time, just peg it at the end of the day
- $endhour = $curappt{"starthour"} + $curappt{"endhour"};
- $endmin = $curappt{"startmin"} + $curappt{"endmin"};
- $endhour = $endhour + int ($endmin / 60);
- $endmin = $endmin % 60;
- $curappt{"endhour"} = $endhour;
- $curappt{"endmin"} = $endmin;
- if ($endhour >= 24) {
- $curappt{"endhour"} = 23;
- $curappt{"endmin"} = 55;
- }
- }
- }
-
- sub output
- {
- $outline = shift(@_);
- print VCALFILE $outline;
- print VCALFILE "\n";
- # print($outline);
- # print("\n");
- }
-
- sub write_header
- {
- output("BEGIN:VCALENDAR");
- output("PRODID:-//K Desktop Environment//NONSGML KOrganizer//EN");
- output("VERSION:1.0");
- }
-
- sub write_footer
- {
- output("END:VCALENDAR");
- }
-
- sub write_appointment
- {
- if (defined($curappt{"tossme"})) {
- return;
- }
-
- if (defined($curappt{"todo"})) {
- output("BEGIN:VTODO");
- } else {
- output("BEGIN:VEVENT");
- }
- $tmpstr = &date_to_str($curappt{"startyear"},
- $curappt{"startmonth"},
- $curappt{"startday"});
- if (defined($curappt{"starthour"})) {
- $tmpstr = $tmpstr . &time_to_str($curappt{"starthour"},
- $curappt{"startmin"});
- } else {
- $tmpstr = $tmpstr . &time_to_str("0","0");
- }
- output("DCREATED:" . $tmpstr);
- output("UID:" . $curappt{"uid"});
- output("SEQUENCE:0");
- output("LAST-MODIFIED:$tmpstr");
- output("DTSTART:$tmpstr");
- if (defined($curappt{"starthour"})) {
- $tmpstr = &date_to_str($curappt{"startyear"},
- $curappt{"startmonth"},
- $curappt{"startday"}) .
- &time_to_str($curappt{"endhour"},
- $curappt{"endmin"});
- }
- output("DTEND:$tmpstr");
- if (defined($curappt{"summary"})) {
- $summary = $curappt{"summary"};
- output("SUMMARY:$summary");
- }
- if (defined($curappt{"description"})) {
- $description = $curappt{"description"};
- output("DESCRIPTION:$description");
- }
- if (defined($curappt{"attendee"})) {
- $attendee = "ATTENDEE;ROLE=OWNER:" . $curappt{"attendee"};
- output($attendee);
- }
-
- if (defined($curappt{"alarm"})) {
-
- }
-
- if (defined($curappt{"repeats"})) {
- # wow what a mess
- $rule = "RRULE:";
- if ($curappt{"repeats"} eq "DAILY") {
- $rule = $rule . "D" . $curappt{"period"};
- } elsif ($curappt{"repeats"} eq "WEEKLY") {
- $rule = $rule . "W1" . " ";
- $rule = $rule . $curappt{"weekdays"};
-
- } elsif ($curappt{"repeats"} eq "MONTHLY") {
- $rule = $rule . "MD" . $curappt{"period"};
- $rule = $rule . " " . $curappt{"startday"};
- }
- if ($curappt{"endrepeat"} && ($curappt{"endrepeat"} =~ /T/)) {
- $rule = $rule . " " . $curappt{"endrepeat"};
- } elsif ($curappt{"endrepeat"}) {
- $rule = $rule . " \#" . $curappt{"endrepeat"};
- } else {
- $rule = $rule . " \#0";
- }
- output($rule);
- }
- if (defined($curappt{"exceptions"})) {
- $exceptions = "EXDATE:" . $curappt{"exceptions"};
- chop($exceptions);
- output($exceptions);
- }
- if (defined($curappt{"todo"})) {
- if (defined($curappt{"done"})) {
- output("STATUS:COMPLETED");
- } else {
- output("STATUS:NEEDS ACTION");
- }
- }
- output("CLASS:PUBLIC");
- output("PRIORITY:0");
- output("TRANSP:0");
- output("RELATED-TO:0");
- if (defined($curappt{"todo"})) {
- output("END:VTODO\n");
- } else {
- output("END:VEVENT\n");
- }
- }
-
- sub date_to_str
- {
- $year = shift(@_);
- $month = shift(@_);
- $day = shift(@_);
- my($datestr);
- $datestr = sprintf("%04d%02d%02d",$year,$month,$day);
- return $datestr;
- }
-
- sub time_to_str
- {
- $hour = shift(@_);
- $min = shift(@_);
- my($timestr);
-
- $timestr = sprintf("T%02d%02d00",$hour,$min);
- return $timestr;
- }
-
- sub process_dates
- {
- # first, test for single
- $_ = $line;
- if (/\[Single/) {
- &repeat_none;
- } elsif (/\[Days/) {
- &repeat_daily;
- } elsif (/\[WeekDays/) {
- &repeat_weekly;
- } elsif (/\[Months/) {
- &repeat_monthly;
- } elsif (/\[ComplexMonths/) {
- $exitstatus = 1;
- #printf("WARNING: complex repeating month entry detected, we don't support.\n");
- #printf("converting to a single occurrence on the original start date.\n");
- $line = &getLine;
- &repeat_none;
- } elsif (/\[Empty/) {
- # silently toss
- $curappt{"tossme"} = "TRUE";
- } else {
- $exitstatus = 1;
- #print "didn't understand line: $_";
- }
- while ($line = &getLine) {
- if ($line =~ /^\]/) {
- return;
- } elsif ($line =~ /^Finish/) {
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- $curappt{"endrepeat"} = &date_to_str($year, $month, $day);
- $curappt{"endrepeat"} = $curappt{"endrepeat"} . &time_to_str("0","0");
- } elsif ($line =~ /^Deleted/) {
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- if (defined($curappt{"exceptions"})) {
- $curappt{"exceptions"} = $curappt{"exceptions"} .
- &date_to_str($year, $month, $day) . ";";
- } else {
- $curappt{"exceptions"} = &date_to_str($year, $month, $day) .
- ";";
- }
- } else {
- $exitstatus = 1;
- #print "trashed line: $line";
- }
- }
- }
-
- sub repeat_none
- {
- # just a one time shot
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- $curappt{"startmonth"} = $month;
- $curappt{"startday"} = $day;
- $curappt{"startyear"} = $year;
- }
-
- sub repeat_daily
- {
- # repeats on a daily basis
- $curappt{"repeats"} = "DAILY";
- ($skip) = /(\d+)$/;
- $curappt{"period"} = $skip;
- $line = &getLine;
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- $curappt{"startmonth"} = $month;
- $curappt{"startday"} = $day;
- $curappt{"startyear"} = $year;
- }
-
- sub repeat_weekly
- {
- # repeats on a weekly basis, a few days a week
- $curappt{"repeats"} = "WEEKLY";
- $startofdates = index($_,"WeekDays") + length("WeekDays");
- $endofdates = index($_,"Months");
- $datestr = substr($_,$startofdates,($endofdates-$startofdates));
- $datestr =~ s/^\s+//;
- @days = split(/\s+/,$datestr);
- $datestr = "";
- foreach $date (@days) {
- if ($date == 1) {
- $datestr = $datestr . "SU ";
- } elsif ($date == 2) {
- $datestr = $datestr . "MO ";
- } elsif ($date == 3) {
- $datestr = $datestr . "TU ";
- } elsif ($date == 4) {
- $datestr = $datestr . "WE ";
- } elsif ($date == 5) {
- $datestr = $datestr . "TH ";
- } elsif ($date == 6) {
- $datestr = $datestr . "FR ";
- } elsif ($date == 7) {
- $datestr = $datestr . "SA ";
- }
- }
- # remove one trailing whitespace
- chop($datestr);
- $curappt{"weekdays"} = $datestr;
- $line = &getLine;
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- $curappt{"startmonth"} = $month;
- $curappt{"startday"} = $day;
- $curappt{"startyear"} = $year;
- }
-
- sub repeat_monthly
- {
- # repeats on a daily basis
- $curappt{"repeats"} = "MONTHLY";
- ($skip) = /(\d+)$/;
- $curappt{"period"} = $skip;
- $line = &getLine;
- ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
- $curappt{"startmonth"} = $month;
- $curappt{"startday"} = $day;
- $curappt{"startyear"} = $year;
- }
-
-
-